﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using audio.Helper;
using audio.Helper.TcpSocket;
using NAudio.Wave;

namespace audio
{

    public class Server
    {
        /// <summary>
        /// tcp 服务
        /// </summary>
        private TcpService _server;


        ///// <summary>
        ///// 主题集合
        ///// LinkedList 客户端集合
        ///// </summary>
        //public Dictionary<string, LinkedList<ClientModel>> Topic = new Dictionary<string, LinkedList<ClientModel>>();


        public Dictionary<IDataTransmit, Stream> ClientDictionary = new Dictionary<IDataTransmit, Stream>();

        /// <summary>
        /// 构造方法
        /// </summary> 
        /// <param name="port"></param> 
        /// <param name="logManager"></param>
        public Server(int port, ILog logManager)
        {
            LogManager = logManager;
            //在指定端口上建立监听线程
            _server = new TcpService(port);
            _server.Connected += server_Connected;
            _server.DisConnect += server_DisConnect;
        }
        public event Action<string, string> LogEvent;
        /// <summary>
        /// 日志管理器
        /// </summary>
        protected readonly ILog LogManager;
        protected virtual void Log(string title, string message)
        {
            LogManager?.Info(title, message);
            LogEvent?.Invoke(title, message);
        }


        /// <summary>
        /// 连接开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void server_Connected(IDataTransmit sender, NetEventArgs e)
        {
            try
            {
                sender.ReceiveData += ReceiveData;
                //接收数据
                sender.Start();
                using (FileStream fs = File.OpenRead(@"刚好遇见你 - 李玉刚 .mp3"))
                {
                    int length = (int)fs.Length;
                    byte[] data = new byte[length];
                    fs.Position = 0;
                    fs.Read(data, 0, length);
                    MemoryStream ms = new MemoryStream(data);
                    ClientDictionary.Add(sender, ms);
                }
                Log(sender.RemoteEndPoint + " 连接成功", null);

            }
            catch (Exception ex)
            {
                LogManager?.Error(ex);
            }

        }

        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void server_DisConnect(IDataTransmit sender, NetEventArgs e)
        {
            if (ClientDictionary.ContainsKey(sender))
            {
                ClientDictionary.Remove(sender);
            }
        }

        readonly byte[] _buffer = new byte[16384 * 4];
        IMp3FrameDecompressor _decompressor;
        private BufferedWaveProvider _bufferedWaveProvider;

        //  Dictionary<System.Net.EndPoint, byte[]> _cache = new Dictionary<EndPoint, byte[]>();

        readonly Dictionary<IDataTransmit, Queue<byte[]>> _cache = new Dictionary<IDataTransmit, Queue<byte[]>>();
        /// <summary>
        /// 接收消息 处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReceiveData(IDataTransmit sender, NetEventArgs e)
        {
            try
            {
                if (ClientDictionary.ContainsKey(sender))
                {
                    bool isCache = false;
                    Queue<byte[]> caches;
                    if (_cache.ContainsKey(sender))
                    {
                        //_cache[sender].SetValue(null);
                        caches = _cache[sender];
                        if (caches.Count > 0)
                        {
                            isCache = true;//有缓存
                        }
                    }
                    else
                    {
                        caches = new Queue<byte[]>();
                        _cache.Add(sender, caches);
                    }
                    if (isCache)
                    {
                        byte[] temp = caches.Dequeue();
                        if (temp.Length > 1152)
                        {
                            byte[] copy = new byte[1152 + 2];
                            copy[0] = 1;
                            copy[1] = 1;
                            Array.Copy(temp, 0, copy, 2, 1152);

                            byte[] cache = new byte[temp.Length - 1152];
                            Array.Copy(temp, 1152, cache, 0, temp.Length - 1152);

                            caches.Enqueue(cache);
                            sender.Send(copy);
                        }
                        else
                        {
                            byte[] copy = new byte[temp.Length + 2];
                            copy[0] = 1;
                            copy[1] = 2;
                            Array.Copy(temp, 0, copy, 2, temp.Length);
                            sender.Send(copy);
                        }

                    }
                    else
                    {
                        var readFullyStream = ClientDictionary[sender];
                        if (readFullyStream == null)
                        {
                            //readFullyStream = new FileStream(@"D:\刚好遇见你 - 李玉刚 .mp3", FileMode.Open);
                            //ClientDictionary[sender] = readFullyStream;
                        }
                        else
                        {
                            Mp3Frame frame = Mp3Frame.LoadFromStream(readFullyStream);

                            if (frame == null)
                            {

                                ClientDictionary[sender].Close();
                                ClientDictionary[sender].Dispose();
                                ClientDictionary[sender] = null;
                                Log(sender.RemoteEndPoint + " 获取完成", null);
                            }
                            else
                            {
                                //   sender.Send(frame.RawData);


                                if (_decompressor == null)
                                {
                                    //创建描述
                                    WaveFormat waveFormat = new Mp3WaveFormat(
                                            frame.SampleRate,
                                            frame.ChannelMode == ChannelMode.Mono ? 1 : 2,
                                            frame.FrameLength,
                                            frame.BitRate
                                        );
                                    _decompressor = new AcmMp3FrameDecompressor(waveFormat);

                                    _bufferedWaveProvider = new BufferedWaveProvider(_decompressor.OutputFormat)
                                    {
                                        BufferDuration = TimeSpan.FromSeconds(20)
                                    };
                                }
                                int decompressed = _decompressor.DecompressFrame(frame, _buffer, 0);
                                //  _bufferedWaveProvider.AddSamples(_buffer, 0, decompressed);


                                if (decompressed == 0)
                                {
                                    sender.Send(new byte[] { 0, 0 });
                                }
                                else
                                {
                                    if (decompressed > 1152)
                                    {
                                        byte[] copy = new byte[1152 + 2];
                                        copy[0] = 1;
                                        copy[1] = 0;
                                        Array.Copy(_buffer, 0, copy, 2, 1152);
                                        byte[] cache = new byte[decompressed - 1152];
                                        Array.Copy(_buffer, 1152, cache, 0, decompressed - 1152);
                                        caches.Enqueue(cache);
                                        sender.Send(copy);

                                        //byte[] temp = new byte[decompressed];
                                        //Array.Copy(_buffer, 0, temp, 0, decompressed);
                                        //ConIntArra(temp);

                                    }
                                    else
                                    {
                                        byte[] copy = new byte[decompressed + 2];
                                        Array.Copy(_buffer, 0, copy, 2, decompressed);
                                        sender.Send(copy);
                                    }


                                }

                            }

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager?.Error(ex);
            }
        }

        public void ConIntArra(byte[] buffer)
        {
            List<int> it = new List<int>();

            string result = "";
            int i = 0;
            while (i < buffer.Length)
            {
                try
                {
                    //int temp = Convert.ToInt32(buffer[i] << 8 | buffer[i + 1]);
                    //it.Add(temp);
                    //result += "0x" + String.Format("{0:X}", temp) + ",";

                    //int temp = Convert.ToInt32(buffer[i] << 8 | buffer[i + 1]);
                    //it.Add(temp);
                    result += "0x" + string.Format("{0:X}", Convert.ToInt32(buffer[i])) + ",";
                    result += "0x" + string.Format("{0:X}", Convert.ToInt32(buffer[i + 1])) + ",";
                }
                catch (Exception ex)
                {
                    string ss = "";
                }
                i += 2;
            }
            LogManager?.Info("发送 ", result);
            //log.Info(@"数量:" + it.Count + "  ", result);
            string s = "";
        }

        /// <summary>
        /// 开始监听
        /// </summary>
        public void Start()
        {
            _server.Start();
        }

        /// <summary>
        /// 停止监听
        /// </summary>
        public void Stop()
        {
            if (_server != null)
            {
                _server.Close();
                _server = null;
            }
        }
    }
}
